/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.rukopisy.tools.cli;

import cz.mzk.kramerius.commons.Dom4jUtils;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;

/**
 *
 * @author Martin Řehánek <rehan at mzk.cz>
 * 
 * Finds all *.log.xml files that are in some subdir in tei root dir.
 * For each of the (k4 import) log file is found appropriate tei file (signature.tei.xml) 
 * and manuscript/monograph identifier is extracted from log.xml document 
 * and added into tei.xml document
 */
public class AddK4PidsAction implements Action {

    private static final Logger logger = Logger.getLogger(AddK4PidsAction.class.getName());
    private static final XPath k4IdnoXpath = Dom4jUtils.createXPath("/tei:TEI/tei:teiHeader/tei:fileDesc/tei:sourceDesc/tei:msDesc/tei:msIdentifier/tei:altIdentifier[@type='other']/tei:idno[@type='k4_pid']");
    private static final XPath msIdentifierXpath = Dom4jUtils.createXPath("/tei:TEI/tei:teiHeader/tei:fileDesc/tei:sourceDesc/tei:msDesc/tei:msIdentifier");
    private static String K4_IMPORT_LOG_SUFFIX = ".log.xml";//TODO: predelat na .k4-import.log.xml
    private static String TEI_SUFFIX = ".tei.xml";
    private File rootDir;
    private String repositoryUrl;

    public AddK4PidsAction(File rootDir, String repositoryUrl) {
        this.rootDir = rootDir;
        this.repositoryUrl = repositoryUrl;
    }

    public void run() {
        List<File> foxmlLogs = findFoxmlLogs();
        for (File foxmlLog : foxmlLogs) {
            updateTeiFile(foxmlLog);
        }
    }

    private List<File> findFoxmlLogs() {
        List<File> result = new ArrayList<File>(0);
        for (File potentialDir : rootDir.listFiles()) {
            if (potentialDir.isDirectory()) {
                List<File> foxmlLogsInDir = findFoxmlLogsInDir(potentialDir);
                result.addAll(foxmlLogsInDir);
            }
        }
        return result;
    }

    private List<File> findFoxmlLogsInDir(File metadataDir) {
        return Arrays.asList(metadataDir.listFiles(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return name.endsWith(K4_IMPORT_LOG_SUFFIX);
            }
        }));
    }

    private void updateTeiFile(File foxmlLog) {
        try {
            logger.log(Level.INFO, "log file: {0}", foxmlLog.getAbsolutePath());
            File teiFile = buildTeiFile(foxmlLog);
            logger.log(Level.INFO, "tei file: {0}", teiFile.getAbsolutePath());
            String monographPid = findMonographPid(foxmlLog);
            logger.log(Level.INFO, "pid: {0}", monographPid);
            Document teiDoc = Dom4jUtils.loadDocument(teiFile, false);
            if (alreadyHasMonographPid(teiDoc)) {
                logger.log(Level.WARNING, "tei file {0} alredy contains k4 pid", teiFile.getAbsolutePath());
            } else {
                updateTei(teiDoc, monographPid);
                Dom4jUtils.saveDocument(teiDoc, teiFile);
            }
        } catch (Exception ex) {
            logger.log(Level.SEVERE, foxmlLog.getAbsolutePath(), ex);
        }

    }

    private String findMonographPid(File foxmlLog) throws Exception {
        Document doc = Dom4jUtils.loadDocument(foxmlLog, false);
        XPath xpath = DocumentHelper.createXPath("/manuscript/model_monograph/pid");
        Node node = xpath.selectSingleNode(doc);
        if (node == null) {
            throw new Exception("pid not found");
        }
        return node.getText();
    }

    private File buildTeiFile(File foxmlLog) {
        String logPath = foxmlLog.getAbsolutePath();
        int end = logPath.length() - K4_IMPORT_LOG_SUFFIX.length();
        String withoutSuffix = logPath.substring(0, end);
        String teiPath = withoutSuffix + TEI_SUFFIX;
        return new File(teiPath);
    }

    private boolean alreadyHasMonographPid(Document teiDoc) {
        Node result = k4IdnoXpath.selectSingleNode(teiDoc);
        return result != null;
    }

    private void updateTei(Document teiDoc, String monographPid) throws Exception {
        System.out.println("updating");
        Element msIdentifier = (Element) msIdentifierXpath.selectSingleNode(teiDoc);
        if (msIdentifier == null) {
            throw new Exception("cannot find msIdentifier");
        }
        Element altId = msIdentifier.addElement("altIdentifier");
        altId.addAttribute("type", "other");
        Element repository = altId.addElement("repository");
        repository.addText(repositoryUrl);
        Element idno = altId.addElement("idno");
        idno.addAttribute("type", "k4_pid");
        idno.addText(monographPid);
    }
}
